﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using WindowsInput;
using System.Windows.Shapes;
using System.Timers;
using TTIServer.TTISettings;
using System.Drawing.Imaging;
using System.Drawing;
using WCintiqHID;

using System.Windows.Interop;
using System.Threading;

namespace TTIServer.TTISettings.Pages
{
     /// <summary>
     /// Interaction logic for DisplaySettings.xaml
     /// </summary>
     public partial class PASWindowClass : Window
     {
          private System.Timers.Timer dispTimer = new System.Timers.Timer(3000);
          private System.Timers.Timer checkTimer = new System.Timers.Timer(250);

          private int DeltaX=0, DeltaY=0;
          private HidDevice.PowerMate.RotationalDirection theRotation;

          public const double PixelScale = 4;
		  public double XLimit;
		  public double YLimit;
		  //public double CintiqRectScaleWidth;
		  //public double CintiqRectScaleHeight;

          WCintiqHID.Cintiq_K wCintiqRef;

          Rect CintiqBounds;

          private bool displayForm = false;
          private bool isButtonDown = false;
          private bool doFadeIn = true;
          private bool isFadingIn = false;
          private bool isFadingOut = false;
          private bool fadeReversed = false;
          private bool isInit = true;

          delegate void SetRenderTransformCallBack(TranslateTransform myTransform);
          delegate void TwoArgCallback(int x, int y, HidDevice.PowerMate.RotationalDirection Rotation);
          delegate void VisibilityCallBack();

          public static TranslateTransform myTT = new TranslateTransform(1, 0);

          private HidDevice.PowerMate myPM = new HidDevice.PowerMate();

          public System.Windows.Shapes.Rectangle PASRectangle;

          Storyboard mySB_FadeIn, mySB_FadeOut;

          
          private static BitmapSource CopyScreen()
          {
               using (var screenBmp = new Bitmap(
                   (int)SystemParameters.VirtualScreenWidth,
                   (int)SystemParameters.VirtualScreenHeight,
                   System.Drawing.Imaging.PixelFormat.Format32bppArgb))
               {
                    using (var bmpGraphics = Graphics.FromImage(screenBmp))
                    {
                         bmpGraphics.CopyFromScreen((int)SystemParameters.VirtualScreenLeft, (int)SystemParameters.VirtualScreenTop, 0, 0, screenBmp.Size);
                         return Imaging.CreateBitmapSourceFromHBitmap(
                             screenBmp.GetHbitmap(),
                             IntPtr.Zero,
                             Int32Rect.Empty,
                             BitmapSizeOptions.FromEmptyOptions());
                    }
               }
          }

          private static BitmapSource CopyPrimaryScreen()
          {
               using (var screenBmp = new Bitmap(
                   (int)SystemParameters.PrimaryScreenWidth,
                   (int)SystemParameters.PrimaryScreenHeight,
                   System.Drawing.Imaging.PixelFormat.Format32bppArgb))
               {
                    using (var bmpGraphics = Graphics.FromImage(screenBmp))
                    {
                         bmpGraphics.CopyFromScreen(0, 0, 0, 0, screenBmp.Size);
                         return Imaging.CreateBitmapSourceFromHBitmap(
                             screenBmp.GetHbitmap(),
                             IntPtr.Zero,
                             Int32Rect.Empty,
                             BitmapSizeOptions.FromEmptyOptions());
                    }
               }
          }  
         

          public PASWindowClass( WCintiqHID.Cintiq_K inTablet)
          {
               InitializeComponent();
               dispTimer.Elapsed += new ElapsedEventHandler(dispTimer_Elapsed);
               checkTimer.Elapsed += new ElapsedEventHandler(checkTimer_Elapsed);
               checkTimer.Start();
               this.Show();

			  switch (inTablet.GetPID())
			  {

				  case 0xCC:
					  CintiqBounds = new Rect(0, 0, 1600, 1200);					  
					  break;
				  case 0xF8:
					  CintiqBounds = new Rect(0, 0, 1920, 1200);
					  break;

			  }

			  

               wCintiqRef = inTablet;

			   XLimit = (SystemParameters.PrimaryScreenWidth - CintiqBounds.Width) / PixelScale;
			   YLimit = (SystemParameters.PrimaryScreenHeight - CintiqBounds.Height) / PixelScale;

               PASScrImg.BeginInit();
               PASScrImg.Source = CopyPrimaryScreen();
               PASScrImg.EndInit();

          }

          public void TranslateRectangle (TranslateTransform inTT)
          {

               //PASRectangle.RenderTransform = inTT;
          }

          public void setPASBoxLocation(int x, int y, HidDevice.PowerMate.RotationalDirection Rotation)
          {
               //if (isInit)
               //{
               //     isInit = false;
               //     return;
               //}
               XLabel.Content = x.ToString();
               YLabel.Content = y.ToString();



               

               double scaledXPix, ScaledYPix;

               //<!--<Rectangle x:Name="PASRectangle" Height="225" Width="300" MinWidth="8" StrokeThickness="2" Opacity="0.85" Stroke="Red" Fill="#FF979797" RenderTransformOrigin="0.5,0.5">

               

               ScaledYPix = y * PixelScale;
               scaledXPix = x * PixelScale;

               CintiqBounds.X = scaledXPix;
               CintiqBounds.Y = ScaledYPix;

               int XMovVal = (int)scaledXPix, YMovVal = (int)ScaledYPix;

               if (theRotation == HidDevice.PowerMate.RotationalDirection.Right)
               {
                    XMovVal += (int)CintiqBounds.Width;
                    YMovVal += (int)CintiqBounds.Height;
               }


               XMovVal *= (int)(65535.0 / SystemParameters.PrimaryScreenWidth);
               YMovVal *= (int)(65535.0 / SystemParameters.PrimaryScreenHeight);

               if (x == XLimit)
                    XMovVal = 65535;

               if (y == YLimit)
                    YMovVal = 65535;

               WindowsInput.InputSimulator.SimulateMouseMouve(XMovVal, YMovVal);

               if (PASRectangle!=null)
                    PASMasterCanvas.Children.Remove(PASRectangle);


               PASRectangle = new System.Windows.Shapes.Rectangle();
              
 

			  PASRectangle.Width = CintiqBounds.Width / PixelScale;
               PASRectangle.Height = CintiqBounds.Height / PixelScale;
               PASRectangle.StrokeThickness = 2;
               PASRectangle.Opacity = 0.85;
               PASRectangle.Stroke = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(0xFF, 0, 0));
               PASRectangle.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(0xff, 0x97, 0x97, 0x97));
			   
 			  
			  PASRectangle.RenderTransformOrigin = new System.Windows.Point(0.0, 0.0);
               PASRectangle.RenderTransform = new TranslateTransform(x, y);
               PASMasterCanvas.Children.Add(PASRectangle);

               //Do Cintiq Magic Here!
               ScreenFactorClass theSFC = new ScreenFactorClass();

               theSFC.CintiqXLoc = (ushort)CintiqBounds.X;
               theSFC.CintiqYLoc = (ushort)CintiqBounds.Y;
			   theSFC.XFactor = (ushort)((SystemParameters.PrimaryScreenHeight * 1000) / (ushort)CintiqBounds.Height);
               theSFC.YFactor = (ushort)((SystemParameters.PrimaryScreenWidth * 1000) / (ushort)CintiqBounds.Width);
               theSFC.Enable = true;

               wCintiqRef.SendNewDisplayCoords(theSFC);


          }

          public void HideForm()
          {

               
          
               mySB_FadeOut.Begin();
               isFadingOut = true;
               //this.Hide();

          }

          public void FadeOutCompleted(object sender, EventArgs e)
          {


                    Hide();
                    doFadeIn = true;
                    isFadingOut = false;

          }

          public void FadeInCompleted(object sender, EventArgs e)
          {
               isFadingIn = false;
          }

          public void ShowForm()
          {

               
               this.Show();

               //if (isFadingOut)
               //{
               //     //TODO: set the opactity value of fade out to fade in, and start fade in
               //     mySB_FadeOut.Pause();
               //     Opacity = 0.75;
               //     doFadeIn = false;
               //     fadeReversed = true;
               //}

               if (doFadeIn)
               {
                    PASScrImg.BeginInit();
                    PASScrImg.Source = CopyPrimaryScreen();
                    PASScrImg.EndInit();
                    mySB_FadeIn.Begin();
               }

               
               doFadeIn = false;

          }

          public void dispTimer_Elapsed(object source, ElapsedEventArgs e)
          {

               dispTimer.Stop();
               this.Dispatcher.BeginInvoke(new VisibilityCallBack(HideForm));


          }

          public void checkTimer_Elapsed(object source, ElapsedEventArgs e)
          {

               if (displayForm)
               {
                    displayForm = false;
                    //this.Visibility = Visibility.Visible;
                    //this.Show();
                    
                    //DELEGATE!
                    this.Dispatcher.BeginInvoke(new TwoArgCallback(setPASBoxLocation), new object[] { DeltaX, DeltaY, theRotation });
                    
                    if (dispTimer.Enabled)
                         dispTimer.Stop();
                    dispTimer.Start();
               }
                    

          }

          public void startTimer()
          {
               if (dispTimer.Enabled)
                    dispTimer.Stop();

               dispTimer.Start();

          }

          public void SetDisplayWindow( bool newVal )
          {
               return;
          }

          public void SetDeltaValues(int x, int y, HidDevice.PowerMate.RotationalDirection Rotation)
          {

               if (x < 0)
                    x = 0;

               if (x > XLimit)
                    x = (int)XLimit;

               if (y > YLimit)
                    y = (int)YLimit;

               if (y < 0)
                    y = 0;

               DeltaX = x;
               DeltaY = y;
               theRotation = Rotation;
               displayForm = true;

          }

          private void PASWindow_Loaded(object sender, RoutedEventArgs e)
          {
               
               checkTimer.Start();

               //Initialize PowerMate
               if (!myPM.Initialize())
               {
                    System.Windows.Forms.MessageBox.Show(@"PowerMate failed to initialize.");
               }

               myPM.ButtonEvent += new HidDevice.PowerMate.ButtonHandler(OnButtonEvent);
               myPM.RotateEvent += new HidDevice.PowerMate.RotationHandler(OnRotateEvent);

               myPM.LowerBound = -1;
               myPM.UpperBound = 1;

               mySB_FadeIn = this.FindResource("FadeIn") as Storyboard;
               mySB_FadeOut = this.FindResource("FadeOut") as Storyboard;
          }

          void OnRotateEvent(HidDevice.PowerMate.RotationalDirection direction, int value)
          {

               if (!isButtonDown)
                    SetDeltaValues(DeltaX+value, DeltaY, direction);
               else
                    SetDeltaValues(DeltaX, DeltaY+value, direction);

               this.Dispatcher.BeginInvoke(new VisibilityCallBack(ShowForm));
          }


          void OnButtonEvent(HidDevice.PowerMate.ButtonState bs)
          {

               if (bs == HidDevice.PowerMate.ButtonState.Down)
               {

                    isButtonDown = true;
               }
               else
               {
                    isButtonDown = false;

               }


			   //switch (this.IsVisible)
			   //{
			   //	 case false:
			   //		this.Dispatcher.BeginInvoke(new VisibilityCallBack(ShowForm));
                         
			   //		  break;
			   //	 case true:
			   //		  this.Dispatcher.BeginInvoke(new VisibilityCallBack(HideForm));
			   //		  break;
			   //}
          }

          private void PASWindow_Unloaded(object sender, RoutedEventArgs e)
          {
               myPM.Shutdown();
          }

     }
}
